﻿using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using System.ServiceModel;
using System.Threading;
using System.Web;
using Metro.Kashikoi.Common;
using Metro.Kashikoi.ServiceContract.Location;
using Metro.Kashikoi.ServiceContract.Security;

namespace Metro.Kashikoi.Service.Common.Security
{
    /// <summary>
    /// This class provides the security context.
    /// </summary>
    public class SecurityContext
    {
        #region Public Methods

        /// <summary>
        /// Gets the primary identity.
        /// </summary>
        /// <returns>The instance of the <c>IIdentity</c>.</returns>
        public static IIdentity GetPrimaryIdentity()
        {
            if (ServiceSecurityContext.Current != null)
            {
                return ServiceSecurityContext.Current.PrimaryIdentity;
            }
            else if (HttpContext.Current != null &&
                HttpContext.Current.Session != null)
            {
                return HttpContext.Current.Session[Constants.SessionIdentity] as IIdentity;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Generates the principal.
        /// </summary>
        /// <param name="identity">The identity.</param>
        /// <param name="userGroup">The user group.</param>
        /// <returns>The newly created <c>IPrincipal</c>.</returns>
        public static IPrincipal GeneratePrincipal(IIdentity identity, UserGroup userGroup)
        {
            if (identity == null)
            {
                throw new SecurityException();
            }
            GenericPrincipal principal = new GenericPrincipal(identity, new string[] 
            { 
                //"Organization 1 Update", 
                //"Facility 3 Delete", 
                // TODO Generate the IPermission role.
                "Admin",
            });
            Thread.CurrentPrincipal = principal;
            return principal;
        }

        /// <summary>
        /// Authorizations the specified region.
        /// </summary>
        /// <param name="region">The region.</param>
        /// <param name="operation">The operation.</param>
        public static void Authorization(Region region, Permission operation)
        {
            IPermission permission = GetPermission(region, operation);
            permission.Demand();
        } 

        #endregion

        #region Private Methods

        private static IPermission GetPermission(Region region, Permission operation)
        {
            var permission = new PrincipalPermission(null,
                // TODO Generate the IPermission role.
                "Admin");
            //string.Format("{0} {1} {2}", region.GetType().Name, region.Id, operation.Id));
            if (region.Parent != null)
            {
                return permission.Union(GetPermission(region.Parent, operation));
            }
            else
            {
                return permission;
            }
        } 

        #endregion
    }
}
